package com.uow.algdemo.algorithms;

import java.util.ArrayList;
import java.util.List;
import android.util.Log;

/**
 * This class will receive data of the Hanoi Tower and solve the problem, then generate animation steps.
 */
public class Hanoi
{
	private int[] panels;
    /**
     * This is the number of panels waiting for sort.
     */
	private int total;
    /**
     * This array contains steps of Hanoi Tower solution.
     */
	private List<int[][]> steps = new ArrayList<int[][]>();

    /**
     * @param newPanels Number of disks.
     */
	public Hanoi(int newPanels)
	{
		total = newPanels;
	}
	/**
	 * @return The steps of Hanoi Tower solution.
	 */
	public List<int[][]> getSteps()
	{
		return steps;
	}
    /**
     * This method records steps for move a panel from original stick to target stick.
     * @param panalNumber Index of panel moving.
     * @param orgStick Index of original stick.
     * @param tarStick Index of target stick.
     */
	private void move(int orgStick, int tarStick)
	{
		int index = getTopPanelIndex(orgStick);
		panels[index] = tarStick;
		int[][] step = new int[3][1];
		step[0][0] = index;
		step[1][0] = orgStick;
		step[2][0] = tarStick;
		
		steps.add(step);
		Log.v("Hanoi", "Move the top plate index of " + index + " from " + orgStick + " to " + tarStick);
	}
    /**
     * This method is main function for the Tower of Hanoi.
     * @param n Number of disks.
     * @param chA Index of first stick.
     * @param chB Index of second stick.
     * @param chC Index of third stick.
     */
	private void HanoiY(int n,int chA,int chB,int chC)
    {
        if(n==1)
            move(chA,chC);
        else
        {
            HanoiY(n-1,chA,chC,chB);
            this.move(chA,chC);
            HanoiY(n-1,chB,chA,chC);
        }
    }
	/**
     * This method solve the Hanoi Tower problem and records all steps in list of steps.
     */
	public void runHanoiTower()
	{
		steps.clear();
		panels = new int[total];
		for(int i = 0; i < total; i++)
		{
			panels[i] = 0;
		}
		HanoiY(total,0,1,2);
	}
	/**
     * This method return index of the first disk of a stick.
     * @param Index index of target stick.
     * @return Index of the first disk of the stick.
     */
	private int getTopPanelIndex(int index)
	{
		for(int i = 0; i < total; i++)
		{
			if(panels[i] == index)
			{
				return i;
			}
		}
		
		return -1;
	}
}
